"""
1. 请写出列表支持的所有方法及说明（例如: append 向列表末尾添加元素）

append(element): 在列表末尾添加一个元素。
extend(iterable): 将可迭代对象中的元素逐个添加到列表末尾。
insert(index, element): 在指定索引位置插入一个元素。
remove(element): 从列表中移除首次出现的指定元素。
pop(index): 移除并返回指定索引位置的元素，如果未指定索引，则移除并返回最后一个元素。
index(element): 返回首次出现指定元素的索引。
count(element): 返回列表中指定元素的出现次数。
sort(): 对列表进行就地排序（升序）。
reverse(): 将列表中的元素反转顺序。
copy(): 创建并返回列表的一个浅拷贝（副本）。
clear(): 移除列表中的所有元素，使其变为空列表。

2. 说明列表的浅拷贝和深拷贝的区别
    shadow copy  
    影子拷贝，也叫浅拷贝。遇到引用类型数据，仅仅复制一
    个引用而已

    deep copy
    往往会递归复制一定深度

    浅拷贝仅复制了列表的一层，而深拷贝则递归地复制了所有
    嵌套对象，以创建一个完全独立的副本。这意味着在处理包
    含嵌套对象的复杂数据结构时，深拷贝通常更安全，因为它
    可以防止意外的副作用和数据共享问题。
    

3. 说明列表和元组的相同点和不同点
   相同点：
        都可以用于存储多个元素，可以包含不同类型的对象，包括数字、字符串、列表、元组等。
        支持索引和切片操作，可以通过索引访问特定位置的元素，也可以使用切片获取子集。
        可以使用 len() 函数获取元素的数量。
        可以迭代（遍历）其中的元素。
        可以使用运算符 + 进行合并操作。
        可以通过比较运算符进行比较操作。
    不同点：
        可变性：列表是可变的（Mutable），意味着可以添加、删除或修改其中的元素。而元组
        是不可变的（Immutable），一旦创建，就无法修改其中的元素。
        语法表示：列表使用方括号 [ ] 表示，元素之间用逗号 , 分隔。元组使用圆括号 ( ) 
        表示，元素之间也用逗号 , 分隔，但通常可以省略圆括号。
        可变性影响：由于列表是可变的，可以执行原地修改操作，如添加、删除、修改元素。
        而元组是不可变的，不能原地修改，只能通过创建新的元组来实现类似的操作。
        使用场景：列表适用于需要频繁修改和操作元素的情况，而元组适用于需要保持数据不
        变性和结构的情况，例如用作函数的参数或返回
        

4. 请写出字符串支持的所有方法及说明（例如: lower 返回字符串的小写）
    以下是一些常用的字符串方法及其说明：
    capitalize(): 将字符串的第一个字符转为大写，其他字符转为小写。
casefold(): 返回字符串的一个全小写的副本，用于不区分大小写的比较。
center(width[, fillchar]): 返回一个指定宽度的居中对齐的字符串，可选择填充字符。
count(sub[, start[, end]]): 返回子字符串在字符串中出现的次数。
encode([encoding[, errors]]): 将字符串编码为指定编码的字节串。
endswith(suffix[, start[, end]]): 检查字符串是否以指定的后缀结束。
find(sub[, start[, end]]): 返回子字符串在字符串中首次出现的索引，若未找到则返回 -1。
index(sub[, start[, end]]): 返回子字符串在字符串中首次出现的索引，若未找到则引发 ValueError。
isalnum(): 检查字符串是否只包含字母和数字字符。
isalpha(): 检查字符串是否只包含字母字符。
isdigit(): 检查字符串是否只包含数字字符。
islower(): 检查字符串中的字母是否都为小写。
isspace(): 检查字符串是否只包含空白字符。
istitle(): 检查字符串是否符合标题化规则（每个单词首字母大写，其他字母小写）。
isupper(): 检查字符串中的字母是否都为大写。
join(iterable): 将可迭代对象中的元素连接为一个字符串。
lower(): 返回字符串的小写版本。
upper(): 返回字符串的大写版本。
strip([chars]): 返回去除字符串两端指定字符的副本，默认去除空白字符。
replace(old, new[, count]): 返回替换指定子字符串后的新字符串。
split([sep[, maxsplit]]): 返回字符串的分割列表。
startswith(prefix[, start[, end]]): 检查字符串是否以指定的前缀开始。
title(): 返回字符串的标题化版本（每个单词首字母大写，其他字母小写）。
swapcase(): 返回字符串中字母大小写互换后的新字符串。
zfill(width): 返回指定宽度的右对齐字符串，以 0 填充左侧。

"""

logs = '''
111.30.144.7 "POST /mock/login/?t=GET HTTP/1.1" 200 
111.30.144.7 "Get /mock/users/?t=POST HTTP/1.1" 200 
111.13.100.92 "Post /mock/login/ HTTP/1.1" 200 
223.88.60.88 "GET /mock/users/?t=POST HTTP/1.1" 200 
111.30.144.7 "GET /mock/users/ HTTP/1.1" 200 
'''
counts={}

lines = logs.strip().split('\n')

for line in lines:
    parts = line.split()
    #print(parts)
    request_type = parts[1].strip('"').upper()
    if request_type in counts:
        counts[request_type] += 1
    else:
        counts[request_type] = 1

print(counts)

for request_type, count in counts.items():
    print(request_type, count)
    
